#include <stdio.h>
#include <unistd.h>

#include "ohos_init.h"
#include "cmsis_os2.h"
#include "iot_gpio.h"
#include "iot_watchdog.h"
#include "iot_pwm.h"
#include "hi_pwm.h"
#include "hi_io.h"

#define TASK_GPIO 9
#define INTERVAL_TIME 30
#define TASK_STACK_SIZE 1024
#define TASK_PRIO 25

static const uint16_t g_Freqs[] = {
    0, //低音   0
    262, //     1
    294, //     2
    330, //     3
    349, //     4
    392, //     5
    440, //     6
    494, //     7
    415, //#5 
    0, // 
    0, //
    523, //中音11
    587, //    12
    659, //    13
    697, //    14
    784, //    15
    880, //    16
    988, //    17
    831, //#5 
    0, // 
    0, // 
    1046, //高音21
    1175, //   22
    1318, //   23
    1397, //   24
    1568, //   25
    1760, //   26
    1976, //   27 
};// musical scale

static const uint8_t g_Notes[] = {
    13,16,17,
    21,13,13,21,17,13,15,
    16,11,11,16,15,14,13,13,
    14,15,16,17,17,21,21,21,
    22,21,22,16,17,0,13,16,17,
    21,13,13,21,17,13,15,
    16,11,11,16,15,14,13,13,
    14,15,16,17,17,21,21,21,
    17,21,22,17,16
};//Musical Notation
// static const uint8_t g_Notes[] = {
//     3,6,7,
//     11,3,3,11,7,3,5,
//     6,1,1,6,5,4,3,3,
//     4,5,6,7,7,11,11,11,
//     12,11,12,6,7,0,3,6,7,
//     11,3,3,11,7,3,5,
//     6,1,1,6,5,4,3,3,
//     4,5,6,7,7,11,11,11,
//     7,11,12,7,6
// };//Musical Notation

static const uint8_t g_Durations[] = {
     1,1,1,
     2,2,2,2,2,1,5,
     2,2,2,2,2,1,4,1,
     2,2,2,2,2,1,4,1,
     2,1,3,1,5,1,1,1,1,
     2,2,2,2,2,1,5,
     2,2,2,2,2,1,4,1,
     2,2,2,2,2,1,4,1,
     2,1,3,2,16
};//beat
static void MusicTask()
{
    printf("Ruyuan start!\r\n");

    hi_pwm_set_clock(PWM_CLK_XTAL); // 设置时钟源为晶体时钟（40MHz，默认时钟源160MHz）

    for (size_t i = 0; i < sizeof(g_Notes)/sizeof(g_Notes[0]); i++) {
        uint32_t tune = g_Notes[i];
        uint16_t freq = g_Freqs[tune];
        uint32_t Delay = g_Durations[i];      
        IoTPwmStart(0, 50, freq*10);
        sleep(Delay);
        IoTPwmStop(0);
    }
}

static void ExampleEntry(void)
{
    /*INIT*/
    IoTGpioInit(9);// init gpio 9
    IoTGpioSetDir(9, IOT_GPIO_DIR_OUT);// set gpio to be output
    hi_io_set_func(9, 5);// set function to be pwm    
    IoTPwmInit(0);// init pwm

    IoTWatchDogDisable();

    osThreadAttr_t attr;
    attr.name = "MusicTask";
    attr.attr_bits = 0U;
    attr.cb_mem = NULL;
    attr.cb_size = 0U;
    attr.stack_mem = NULL;
    attr.stack_size = TASK_STACK_SIZE;
    attr.priority = TASK_PRIO;

    if (osThreadNew((osThreadFunc_t)MusicTask, NULL, &attr) == NULL)
    {
        printf("[LedExample] Falied to create LedTask!\n");
    }
}

SYS_RUN(ExampleEntry);
